package net.message.processor;

import net.message.*;
import net.Synchronizer;
import net.Sender;
import net.Receiver;
import net.Client;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;

import util.Config;

public class MessageProcessor implements IMessageProcessor {

    private final Synchronizer synchronizer;
    private final Sender sender;

    private final ConcurrentMap<Integer, int[]> images = new ConcurrentHashMap<Integer, int[]>();

    public MessageProcessor(Synchronizer synchronizer, Sender sender) {
        this.synchronizer = synchronizer;
        this.sender = sender;
    }

    public int[] getImage(int imageID) {
        try {
            while (!images.containsKey(imageID)) {
                Thread.sleep(Config.getInstance().getSleepingTime());
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return images.remove(imageID);
    }

    public void setReceivedMessage(int[] image, int imageID) {
        images.putIfAbsent(imageID, image);
    }

    @Override
    public void process(CreateImageMessage message, Client client) {
        synchronizer.addImage(message.imageID, client);
    }

    @Override
    public void process(AliveMessage message, Client client) {
        synchronizer.confirm(client);
    }

    @Override
    public void process(GetImageResponseMessage message, Client client) {
        setReceivedMessage(message.image, message.imageID);
    }

    @Override
    public void process(GetImageRequestMessage message, Client client) {
        sender.sendGetImageResponse(synchronizer.getMyImage(message.iw), message.iw.imageID, client);
    }

    @Override
    public void process(HelloRequestMessage message, Client client) {
        sender.sendHelloResponse(client, synchronizer.getMyImageIDs());
    }

    @Override
    public void process(HelloResponseMessage message, Client client) {
        synchronizer.setImageIDs(client, message.imageIDs);
    }

    @Override
    public void process(JoinImageRequestMessage message, Client client) {
        synchronizer.addImageEditor(message.imageID, client);
        sender.sendJoinImageResponse(client, message.imageID);
    }

    @Override
    public void process(JoinImageResponseMessage message, Client client) {
        synchronizer.addImageEditor(message.imageID, client);
    }

    @Override
    public void process(NewLineMessage message, Client client) {
        synchronizer.drawLine(message.imageID, message.x, message.y, message.dx, message.dy);
    }
}